﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using SUT = Admx_Generator;

namespace Tests_Admx_Generator
{
    public class Test_Adml
    {
        [TestClass]
        public class Constructor_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void CreateANewInstanceWithTheRightCulture_WhenCalled()
            {
                // Arrange
                System.Globalization.CultureInfo expectedCulture;

                // Act
                expectedCulture = new System.Globalization.CultureInfo("fr-FR");

                // Assert
                Assert.AreEqual(expectedCulture, this._adml.Culture);
            }

            [TestMethod]
            public void SetRevisionToOneDotZero_WhenNewInstanceIsCreated()
            {
                // Arrange
                SUT.Revision expectedRevision;

                // Act
                expectedRevision = new SUT.Revision(1, 0);

                // Assert
                Assert.AreEqual(expectedRevision, this._adml.Revision);
            }
        }

        [TestClass]
        public class Revision_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void RaisedOnChangeEvent_WhenRevisionChange()
            {
                // Arrange
                SUT.Revision expectedRevision = new SUT.Revision(2, 3);
                SUT.Revision actualRevision = null;
                this._adml.OnChanged += delegate(SUT.AdmlFile sender) { actualRevision = sender.Revision; };

                // Act
                this._adml.Revision = expectedRevision;

                // Assert
                Assert.AreEqual(expectedRevision, actualRevision);
            }
        }

        [TestClass]
        public class GetString_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void ReturnStringEmpty_WhenCalledWithAnIdThatDoesntExist()
            {
                Assert.AreEqual(String.Empty, this._adml.GetString("unknownId"));
            }

            [TestMethod]
            public void ReturnTheGoodString_WhenCalledWithAValidId()
            {
                // Arrange
                string expectedString = "This is the expected result.";
                string stringId = "MyId";

                // Act
                this._adml.ModifyString(stringId, expectedString);

                // Assert
                Assert.AreEqual(expectedString, this._adml.GetString(stringId));
            }
        }

        [TestClass]
        public class ModifyString_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void ModifyTheString_WhenCalled()
            {
                // Arrange
                string originalString = "This is the original string.";
                string expectedString = "This is the expected result.";
                string stringId = "MyId";

                // Act
                this._adml.ModifyString(stringId, originalString);
                this._adml.ModifyString(stringId, expectedString);

                // Assert
                Assert.AreEqual(expectedString, this._adml.GetString(stringId));
            }

            [TestMethod]
            public void AddTheString_WhenCalledWithAnUnknownId()
            {
                // Arrange
                string originalString = "This is the original string.";
                string expectedString = "This is the expected result.";
                string originalId = "MyId";
                string newId = "newId";

                // Act
                this._adml.ModifyString(originalId, originalString);
                this._adml.ModifyString(newId, expectedString);

                // Assert
                Assert.AreEqual(expectedString, this._adml.GetString(newId));
                Assert.AreEqual(originalString, this._adml.GetString(originalId));
            }
        }

        [TestClass]
        public class DeleteString_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void DeleteTheString_WhenCalled()
            {
                // Arrange
                string id = "MyId";
                string value = "this is the string";

                // Act
                this._adml.ModifyString(id, value);
                Assert.AreEqual(value, this._adml.GetString(id));
                this._adml.DeleteString(id);

                // Assert
                Assert.AreEqual(String.Empty, this._adml.GetString(id));
            }

            [TestMethod]
            public void DoNothing_WhenTryingToDeleteAstringThatDoesntExist()
            {
                // Arrange
                string id = "MyId";
                string value = "this is the string";

                // Act
                this._adml.ModifyString(id, value);
                Assert.AreEqual(value, this._adml.GetString(id));
                this._adml.DeleteString("nothing");

                // Assert
                Assert.AreEqual(value, this._adml.GetString(id));
            }
        }

        [TestClass]
        public class StringExists_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void ReturnTrue_WhenTheStringExists()
            {
                // Arrange
                string newString = "This is a string.";
                string stringId = "stringId";

                // Act
                this._adml.ModifyString(stringId, newString);

                // Assert
                Assert.IsTrue(this._adml.StringExist(stringId));
            }

            [TestMethod]
            public void ReturnFalse_WhenTheStringDoesntExists()
            {
                // Arrange
                string newString = "This is a string.";
                string stringId = "stringId";
                string otherId = "OtherId";

                // Act
                this._adml.ModifyString(stringId, newString);

                // Assert
                Assert.IsFalse(this._adml.StringExist(otherId));
            }
        }

        [TestClass]
        public class GetPresentation_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void ReturnNull_WhenCalledWithAnIdThatDoesntExist()
            {
                Assert.AreEqual(null, this._adml.GetPresentation("unknownId"));
            }

            [TestMethod]
            public void ReturnTheCorrectPresentation_WhenCalledWithAValidID()
            {
                // Arrange
                SUT.IPresentationElement expectedPresentation = new SUT.ComboBoxPresentation("id", "label");
                string stringId = "MyId";

                // Act
                this._adml.ModifyPresentation(stringId, expectedPresentation);

                // Assert
                Assert.AreEqual(expectedPresentation, this._adml.GetPresentation(stringId));
            }
        }

        [TestClass]
        public class ModifyPresentation_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void ModifyThePresentation_WhenCalled()
            {
                // Arrange
                SUT.IPresentationElement originalPresentation = new SUT.TextBoxPresentation("id", "label");
                SUT.IPresentationElement expectedPresentation = new SUT.TextBoxPresentation("id2", "label2");
                string stringId = "MyId";

                // Act
                this._adml.ModifyPresentation(stringId, originalPresentation);
                this._adml.ModifyPresentation(stringId, expectedPresentation);

                // Assert
                Assert.AreEqual(expectedPresentation, this._adml.GetPresentation(stringId));
            }

            [TestMethod]
            public void AddThePresentation_WhenCalledWithAnUnknownId()
            {
                // Arrange
                SUT.IPresentationElement originalPresentation = new SUT.TextBoxPresentation("id", "label");
                SUT.IPresentationElement expectedPresentation = new SUT.TextBoxPresentation("id2", "label2");
                string originalId = "MyId";
                string newId = "newId";

                // Act
                this._adml.ModifyPresentation(originalId, originalPresentation);
                this._adml.ModifyPresentation(newId, expectedPresentation);

                // Assert
                Assert.AreEqual(expectedPresentation, this._adml.GetPresentation(newId));
                Assert.AreEqual(originalPresentation, this._adml.GetPresentation(originalId));
            }
        }
        
        [TestClass]
        public class DeletePresentation_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void DeleteTheString_WhenCalled()
            {
                // Arrange
                string id = "MyId";
                SUT.IPresentationElement expectedPresentation = new SUT.TextBoxPresentation("id2", "label2");

                // Act
                this._adml.ModifyPresentation(id, expectedPresentation);
                Assert.AreEqual(expectedPresentation, this._adml.GetPresentation(id));
                this._adml.DeletePresentation(id);

                // Assert
                Assert.AreEqual(null, this._adml.GetPresentation(id));
            }

            [TestMethod]
            public void DoNothing_WhenTryingToDeleteAstringThatDoesntExist()
            {
                // Arrange
                string id = "MyId";
                SUT.IPresentationElement expectedPresentation = new SUT.TextBoxPresentation("id2", "label2");

                // Act
                this._adml.ModifyPresentation(id, expectedPresentation);
                Assert.AreEqual(expectedPresentation, this._adml.GetPresentation(id));
                this._adml.DeletePresentation("nothing");

                // Assert
                Assert.AreEqual(expectedPresentation, this._adml.GetPresentation(id));
            }
        }

        [TestClass]
        public class PresentationExists_Should
        {            
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }

            [TestMethod]
            public void ReturnTrue_WhenThePresentationExists()
            {
                // Arrange
                SUT.CheckBoxPresentation newPresentation = new SUT.CheckBoxPresentation("id", "value");
                string presentationId = "id";

                // Act
                this._adml.ModifyPresentation(presentationId, newPresentation);

                // Assert
                Assert.IsTrue(this._adml.PresentationExists(presentationId));
            }

            [TestMethod]
            public void ReturnFalse_WhenThePresentationDoesntExists()
            {
                // Arrange
                SUT.CheckBoxPresentation newPresentation = new SUT.CheckBoxPresentation("id", "value");
                string presentationId = "id";
                string otherId = "otherId";

                // Act
                this._adml.ModifyPresentation(presentationId, newPresentation);

                // Assert
                Assert.IsFalse(this._adml.PresentationExists(otherId));
            }
        }

        [TestClass]
        public class Reset_Should
        {
            private SUT.AdmlFile _adml;

            [TestInitialize]
            public void BeforeEachTest()
            {
                this._adml = new SUT.AdmlFile("fr-FR");
            }
            
            [TestMethod]
            public void SetRevisionToOneDotZero_WhenCalled()
            {
                // Arrange
                SUT.Revision newRevision = new SUT.Revision(2, 3);
                SUT.Revision expectedRevision = new SUT.Revision(1, 0);

                // Act
                this._adml.Revision = newRevision;
                this._adml.Reset();

                // Assert
                Assert.AreEqual(expectedRevision, this._adml.Revision);
            }

            [TestMethod]
            public void ClearStringTable_WhenCalled()
            {
                // Arrange
                string stringId = "id";
                string stringValue = "value";

                // Act
                this._adml.ModifyString(stringId, stringValue);
                Assert.IsTrue(this._adml.StringExist(stringId));
                this._adml.Reset();

                // Assert
                Assert.IsFalse(this._adml.StringExist(stringId));
            }

            [TestMethod]
            public void ClearPresentationTable_WhenCalled()
            {
                // Arrange
                SUT.ListBoxPresentation presentation = new SUT.ListBoxPresentation("id", "value");
                string presentationId = "id";

                // Act
                this._adml.ModifyPresentation(presentationId, presentation);
                Assert.IsTrue(this._adml.PresentationExists(presentationId));
                this._adml.Reset();

                // Assert
                Assert.IsFalse(this._adml.PresentationExists(presentationId));
            }

            [TestMethod]
            public void RaisedOnChangeEvent_WhenCalled()
            {
                // Arrange
                bool raised = false;
                this._adml.OnChanged += delegate(SUT.AdmlFile sender) { raised = true; };

                // Act
                this._adml.Reset();

                // Assert
                Assert.IsTrue(raised);
            }
        }
    }
}
